/*
 * @Author: hruomei
 * @Title: 移动中台公共接口
 * @Description: 移动中台公共接口文件
 * @CreateTime: 2019/05/31
 * @LastUpDateTime: 2019/01/20
 * @Version: V1.03
 */

import Vue from 'vue'
import MD5 from 'js-md5';
import {
	Base64
} from 'js-base64'
import CryptoJS from 'crypto-js'

export const THIS = new Vue();
import oaconfig from './config.js'
const lang= require('../../language/zh.js')
//万能的类型检测方法
const checkType = (arr) => {
	return Object.prototype.toString.call(arr).slice(8, -1);
}

Array.prototype.myFlat = function(num) {
	let type = checkType(this);
	let result = [];

	if (!Object.is(type, "Array")) {
		return;
	}

	this.forEach((item) => {
		let cellType = checkType(item);
		if (Object.is(cellType, "Array")) {
			num--;
			if (num < 0) {
				let newArr = result.push(item);
				return newArr;
			}
			result.push(...item.myFlat(num));
		} else {
			result.push(item);
		}
	});

	return result;
}

Array.prototype.indexOf = function(val) {
	for (var i = 0; i < this.length; i++) {
		if (this[i] == val) return i;
	}
	return -1;
};

Date.prototype.Format = function(fmt) {
	var o = {
		"M+": this.getMonth() + 1, //月份
		"d+": this.getDate(), //日
		"H+": this.getHours(), //小时
		"m+": this.getMinutes(), //分
		"s+": this.getSeconds(), //秒
		"q+": Math.floor((this.getMonth() + 3) / 3), //季度
		"S": this.getMilliseconds() //毫秒
	};
	if (/(y+)/.test(fmt)) fmt = fmt.replace(RegExp.$1, (this.getFullYear() + "").substr(4 - RegExp.$1.length));
	for (var k in o)
		if (new RegExp("(" + k + ")").test(fmt)) fmt = fmt.replace(RegExp.$1, (RegExp.$1.length == 1) ? (o[k]) : (("00" + o[
			k]).substr(("" + o[k]).length)));
	return fmt;
};

String.prototype.trim = function() {
	return this.replace(/(^\s*)|(\s*$)/g, "");
};

Array.prototype.del = function(dx) {
	if (isNaN(dx) || dx > this.length) {
		return false;
	}
	this.splice(dx, 1);
}

//表单校验方法
const FormChecker = {
	error: '',
	check: function(data, rule) {
		for (var i = 0; i < rule.length; i++) {
			if (!rule[i].checkType) {
				return true;
			}
			if (!rule[i].name) {
				return true;
			}
			if (!rule[i].errorMsg) {
				return true;
			}
			if (!data[rule[i].name]) {
				this.error = rule[i].errorMsg;
				return false;
			}
			switch (rule[i].checkType) {
				case 'string':
					var reg = new RegExp('^.{' + rule[i].checkRule + '}$');
					if (!reg.test(data[rule[i].name])) {
						this.error = rule[i].errorMsg;
						return false;
					}
					break;
				case 'int':
					var reg = new RegExp('^(-[1-9]|[1-9])[0-9]{' + rule[i].checkRule + '}$');
					if (!reg.test(data[rule[i].name])) {
						this.error = rule[i].errorMsg;
						return false;
					}
					break;
				case 'between':
					if (!this.isNumber(data[rule[i].name])) {
						this.error = rule[i].errorMsg;
						return false;
					}
					var minMax = rule[i].checkRule.split(',');
					minMax[0] = Number(minMax[0]);
					minMax[1] = Number(minMax[1]);
					if (data[rule[i].name] > minMax[1] || data[rule[i].name] < minMax[0]) {
						this.error = rule[i].errorMsg;
						return false;
					}
					break;
				case 'betweenD':
					var reg = /^-?[1-9][0-9]?$/;
					if (!reg.test(data[rule[i].name])) {
						this.error = rule[i].errorMsg;
						return false;
					}
					var minMax = rule[i].checkRule.split(',');
					minMax[0] = Number(minMax[0]);
					minMax[1] = Number(minMax[1]);
					if (data[rule[i].name] > minMax[1] || data[rule[i].name] < minMax[0]) {
						this.error = rule[i].errorMsg;
						return false;
					}
					break;
				case 'betweenF':
					var reg = /^-?[0-9][0-9]?.+[0-9]+$/;
					if (!reg.test(data[rule[i].name])) {
						this.error = rule[i].errorMsg;
						return false;
					}
					var minMax = rule[i].checkRule.split(',');
					minMax[0] = Number(minMax[0]);
					minMax[1] = Number(minMax[1]);
					if (data[rule[i].name] > minMax[1] || data[rule[i].name] < minMax[0]) {
						this.error = rule[i].errorMsg;
						return false;
					}
					break;
				case 'same':
					if (data[rule[i].name] != rule[i].checkRule) {
						this.error = rule[i].errorMsg;
						return false;
					}
					break;
				case 'notsame':
					if (data[rule[i].name] == rule[i].checkRule) {
						this.error = rule[i].errorMsg;
						return false;
					}
					break;
				case 'email':
					var reg = /^\w+([-+.']\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*$/;
					if (!reg.test(data[rule[i].name])) {
						this.error = rule[i].errorMsg;
						return false;
					}
					break;
				case 'phoneno':
					var reg = /^1[0-9]{10,10}$/;
					if (!reg.test(data[rule[i].name])) {
						this.error = rule[i].errorMsg;
						return false;
					}
					break;
				case 'zipcode':
					var reg = /^[0-9]{6}$/;
					if (!reg.test(data[rule[i].name])) {
						this.error = rule[i].errorMsg;
						return false;
					}
					break;
				case 'reg':
					var reg = new RegExp(rule[i].checkRule);
					if (!reg.test(data[rule[i].name])) {
						this.error = rule[i].errorMsg;
						return false;
					}
					break;
				case 'in':
					if (rule[i].checkRule.indexOf(data[rule[i].name]) == -1) {
						this.error = rule[i].errorMsg;
						return false;
					}
					break;
				case 'notnull':
					if (data[rule[i].name] == null || data[rule[i].name].length < 1) {
						this.error = rule[i].errorMsg;
						return false;
					}
					break;
				case 'idcard':
					var reg = /(^\d{15}$)|(^\d{18}$)|(^\d{17}(\d|X|x)$)/;
					if (!reg.test(data[rule[i].name])) {
						this.error = rule[i].errorMsg;
						return false;
					}
					break;
				case 'pwd':
					var reg = oaconfig.passwordReg;
					if (!reg.test(data[rule[i].name])) {
						this.error = rule[i].errorMsg;
						return false;
					}
					break;
			}
		}
		return true;
	},
	isNumber: function(checkVal) {
		var reg = /^-?[1-9][0-9]?.?[0-9]*$/;
		return reg.test(checkVal);
	}
}

// 参数缺省时抛出异常
export function throwIfMissing() {
	throw new Error('Missing parameter');
}

// 防抖
export function debounce(defaultTime) {
	let timeoutIndex;

	return function(callback, time) {
		if (!isNumber(time)) {
			time = defaultTime;
		}

		if (isNumber(timeoutIndex)) {
			clearTimeout(timeoutIndex);
		}

		timeoutIndex = setTimeout(callback, time);
	}
}

// 节流
export function throttle(func, delay = throwIfMissing()) {
	var timer = null;
	var startTime = Date.now();

	return function() {
		var curTime = Date.now();
		var remaining = delay - (curTime - startTime);
		var context = this;
		var args = arguments;

		clearTimeout(timer);

		if (remaining <= 0) {
			func.apply(context, args);
			startTime = Date.now();
		} else {
			timer = setTimeout(func, remaining);
		}
	}
}

// 姓名验证
export function isName(name) {
	return (name.search(/^[\u0391-\uFFE5\w]+$/) != -1);
}

// 邮箱验证
export function isEmail(email) {
	return (email.search(/^([a-zA-Z0-9]+[_|_|.]?)*[a-zA-Z0-9]+@([a-zA-Z0-9]+[_|_|.]?)*[a-zA-Z0-9]+\.(?:com|cn)$/) != -1);
}

// 验证电话号码
export function isTelPhone(telphone) {
	return (telphone.search(/^(([0\+]\d{2,3}-)?(0\d{2,3})-)?(\d{7,8})(-(\d{3,}))?$/) != -1);
}

// 验证手机号码
export function isMobile(tel) {
	return (tel.search(/^(((13[0-9]{1})|(15[0-9]{1}))+\d{8})$/) != -1);
}

// 验证QQ
export function isQQ(qq) {
	return (qq.search(/^[1-9]\d{4,8}$/) != -1);
}

// 生日验证
export function isBirthDay(day) {
	return (day.search(/\d{1,4}\-\d{1,2}\-\d{1,2}/) != -1);
}

// @参数（v）：传入对象
export function isJson(v) {
	return typeof(v) == "object" && Object.prototype.toString.call(v).toLowerCase() == "[object object]" && !v.length;
}

// @参数（v）：传入对象
export function isNumber(v) {
	var reg_exp = /^[0-9]+$/;
	if (v == "") {
		return false;
	}
	return reg_exp.test(v);
}

// @参数（v）：传入对象
export function isArray(v) {
	return Array.isArray(v);
}

// @参数（v）：传入对象
export function isNull(v) {
	return (typeof(v) == 'undefined') ? true : ((v == null) ? true : v === "");
}

// @参数（v）：传入对象
export function isUndefined(obj) {
	return typeof(obj) === "undefined";
}

// @参数（v）：传入对象
export function isString(v) {
	return typeof v !== "undefined" && v !== null && (typeof v === "string" || v.constructor === String);
}

// 判断是否是对象
export function isObject(obj) {
	return obj !== null && typeof obj === 'object';
}

// 判断对象是否是正则表达式
export function isRegExp(v) {
	return Object.prototype.toString.call(v) === '[object RegExp]'
}

// 判断对象是否是方法
export function isFunction(obj) {
	return Object.prototype.toString.call(obj) === "[object Function]"
}

// 判断是否是纯粹的对象
export function isPlainObject(obj) {
	return Object.prototype.toString.call(obj) === '[object Object]';
}

// 判断字符长度，区分中英文
export function strlen(str) {
	var len = 0;
	for (var i = 0; i < str.length; i++) {
		var c = str.charCodeAt(i);
		//单字节加1
		if ((c >= 0x0001 && c <= 0x007e) || (0xff60 <= c && c <= 0xff9f)) {
			len++;
		} else {
			len += 2;
		}
	}
	return len;
}

// 在数组中查找指定值，并返回它的索引值（如果没有找到，则返回-1）
export function inArray(elem, arr, i) {
	var len,
		testArr = [],
		indexOf = testArr.indexOf;
	if (arr) {
		if (indexOf) {
			return indexOf.call(arr, elem, i);
		}
		len = arr.length;
		//alert(inArray(5,[1,2,3,5,4],-1))这里获取到的i就是4，len就是5，返回值为-1
		i = i ? i < 0 ? Math.max(0, len + i) : i : 0;
		for (; i < len; i++) {
			//这里直接跳过稀疏数组中的空白部分，进而节约时间
			if (i in arr && arr[i] === elem) {
				return i;
			}
		}
	}
	return -1;
}

// 合并对象
export function extend() {
	/*@target被扩展的对象 @length参数的数量 @deep是否深度操作　　*/
	var options, name, src, copy, copyIsArray, clone,
		target = arguments[0] || {},
		i = 1,
		length = arguments.length,
		deep = false;

	if (typeof target === "boolean") {
		deep = target;
		target = arguments[1] || {};

		// 将i赋值为2，跳过前两个参数
		i = 2;
	}

	// target既不是对象也不是函数则把target设置为空对象。
	if (!isObject(target) && !isFunction(target)) {
		target = {};
	}

	for (; i < length; i++) {
		if (!isNull(options = arguments[i])) {
			for (name in options) {
				src = target[name];
				copy = options[name];

				if (target === copy) {
					continue;
				}

				if (deep && copy && (isPlainObject(copy) || (copyIsArray = isArray(copy)))) {
					if (copyIsArray) {
						copyIsArray = false;
						clone = src && isArray(src) ? src : [];
					} else {
						clone = src && isObject(src) ? src : {};
					}

					target[name] = extend(deep, clone, copy);

				} else if (!isUndefined(copy)) {
					target[name] = copy;
				}
			}
		}
	}

	return target;
}

// 深度拷贝
export function deepClone(obj) {
	var _self = this
	let objClone = Array.isArray(obj) ? [] : {};
	if (obj && typeof obj === "object") {
		for (var key in obj) {
			if (obj.hasOwnProperty(key)) {
				//判断ojb子元素是否为对象，如果是，递归复制
				if (obj[key] && typeof obj[key] === "object") {
					objClone[key] = _self.deepClone(obj[key]);
				} else {
					//如果不是，简单复制
					objClone[key] = obj[key];
				}
			}
		}
	}
	return objClone;
}

// 获取随机数
export function getRandom() {
	return new Date().getTime();
}

// 获取guid
export function guid() {
	var s = [];
	var hexDigits = "0123456789abcdef";
	for (var i = 0; i < 36; i++) {
		s[i] = hexDigits.substr(Math.floor(Math.random() * 0x10), 1);
	}
	s[14] = "4"; // bits 12-15 of the time_hi_and_version field to 0010
	s[19] = hexDigits.substr((s[19] & 0x3) | 0x8, 1); // bits 6-7 of the clock_seq_hi_and_reserved to 01
	s[8] = s[13] = s[18] = s[23] = "-";
	var uuid = s.join("");
	return uuid;
}

// 表单检验formData:{name:value,name1:value1}  rule:[name:'',checkType:'',checkRule:'',errorMsg:'']
export function formChecked(formData, rule) {
	//定义表单规则
	// var rule = [
	// 	{name:"nickname", checkType : "string", checkRule:"1,3",  errorMsg:"姓名应为1-3个字符"},
	// 	{name:"gender", checkType : "in", checkRule:"男,女",  errorMsg:"请选择性别"},
	// 	{name:"bd", checkType : "notsame", checkRule:"请选择",  errorMsg:"请选择生日"},
	// 	{name:"aihao", checkType : "notnull", checkRule:"",  errorMsg:"请选择爱好"},
	// 	{name:"email", checkType : "email", checkRule:"",  errorMsg:"请填写您的邮箱"}
	// ];
	//进行表单检查
	var checkRes = FormChecker.check(formData, rule);
	if (checkRes) {
		return true;
	} else {
		showModalWithCloseButton(FormChecker.error);
		return false;
	}
}

// 获取请求相对路径
export function getUrlRelativePath(url) {
	var relUrl = url;
	if (relUrl.indexOf('//') != -1) {
		var arrUrl = relUrl.split("//"),
			start = arrUrl[1].indexOf("/");
		relUrl = arrUrl[1].substring(start); //stop省略，截取从start开始到结尾的所有字符
	}

	if (relUrl.indexOf("?") != -1) {
		relUrl = relUrl.split("?")[0];
	}
	return relUrl;
}

// 设置URL参数，保留原有URL的参数
export function setUrlParams(url, params) {
	if (JSON.stringify(params) == "{}") return url;
	let result = '',
		oParam = {},
		param = {};
	if (url.indexOf('?') === '-1') {
		result = url;
	} else {
		result = url.split("?")[0];
		oParam = parseUrlParams(url);
	}
	result += '?';
	param = extend({}, oParam, params);
	for (let i in param) {
		result += (i + "=" + param[i] + "&");
	}
	return result.substr(0, result.length - 1);
}

// 获取路径参数并转换为对象
export function parseUrlParams(url) {
	let search = url.indexOf('?') != -1 ? url.substring(url.lastIndexOf('?') + 1) : '';
	var ret = {},
		seg = search.replace(/^\?/, '').split('&'),
		len = seg.length,
		i = 0,
		s;
	for (; i < len; i++) {
		if (!seg[i]) {
			continue;
		}
		s = seg[i].split('=');
		ret[s[0]] = s[1];
	}
	return ret;
}

// 保留当前页面，跳转到应用内的某个页面，使用navigateBack可以返回到原页面
export function navigateTo(url, data, obj) {
	let routeObj = {
		url: url,
		fail(e) {
			uni.navigateTo({
				url: '/pages/framework/other/pageNotFound'
			});
		}
	};
	if (data && isObject(data)) {
		routeObj.url = setUrlParams(url, data);
	}
	if (obj && isObject(obj)) {
		extend(true, routeObj, obj);
	}
	//是否登录，权限校验等
	// if (hasLogin()) {
	uni.navigateTo(routeObj);
	// }
}

// 关闭当前页面，跳转到应用内的某个页面
export function redirectTo(url, data, obj) {
	//是否登录，权限校验等
	let routeObj = {
		url: url,
		fail(e) {
			uni.navigateTo({
				url: '/pages/framework/other/pageNotFound'
			});
		}
	};
	if (data && isObject(data)) {
		routeObj.url = setUrlParams(url, data);
	}
	if (obj && isObject(obj)) {
		extend(true, routeObj, obj);
	}
	//是否登录，权限校验等
	// if (hasLogin()) {
	uni.redirectTo(routeObj);
	// }
}

// 关闭所有页面，打开到应用内的某个页面
export function reLaunch(url, data, obj) {
	//是否登录，权限校验等
	let routeObj = {
		url: url,
		fail(e) {
			uni.navigateTo({
				url: '/pages/framework/other/pageNotFound'
			});
		}
	};
	if (data && isObject(data)) {
		routeObj.url = setUrlParams(url, data);
	}
	if (obj && isObject(obj)) {
		extend(true, routeObj, obj);
	}
	//是否登录，权限校验等
	// if (hasLogin()) {
	uni.reLaunch(routeObj);
	// }
}

// 跳转到 tabBar 页面，并关闭其他所有非 tabBar 页面
export function switchTab(url, obj) {
	//是否登录，权限校验等
	let routeObj = {
		url: url,
		fail(e) {
			uni.navigateTo({
				url: '/pages/framework/other/pageNotFound'
			});
		}
	};
	if (obj && isObject(obj)) {
		extend(true, routeObj, obj);
	}
	//是否登录，权限校验等
	// if (hasLogin()) {
	uni.switchTab(routeObj);
	// }
}

// 关闭当前页面，返回上一页面或多级页面
export function navigateBack(delta = 1, obj) {
	//是否登录，权限校验等
	let routeObj = {
		delta: delta,
		fail(e) {
			uni.navigateTo({
				url: '/pages/framework/other/pageNotFound'
			});
		}
	};
	if (obj && isObject(obj)) {
		extend(true, routeObj, obj);
	}
	//是否登录，权限校验等
	// if (hasLogin()) {
	uni.navigateBack(routeObj);
	// }
}

// md5加密
export function md5Encript(str = throwIfMissing(), callback) {
	let res = str;
	if (isString(str)) {
		res = MD5(str);
	} else {
		console.warn('Variable type should be "String"');
	}
	if (callback) {
		return callback(res);
	} else {
		return res;
	}
}

// base64编码
export function base64Encript(str = throwIfMissing(), callback) {
	let res = str;
	if (isString(str)) {
		res = Base64.encode(str);
	} else {
		console.warn('Variable type should be "String"');
	}
	if (callback) {
		return callback(res);
	} else {
		return res;
	}
}

// base64解码
export function base64Decript(str = throwIfMissing(), callback) {
	let res = str;
	if (isString(str)) {
		res = Base64.decode(str);
	} else {
		console.warn('Variable type should be "String"');
	}
	if (callback) {
		return callback(res);
	} else {
		return res;
	}
}

// base64编码URI
export function base64EncriptURI(str = throwIfMissing(), callback) {
	let res = str;
	if (isString(str)) {
		res = Base64.encodeURI(str);
	} else {
		console.warn('Variable type should be "String"');
	}
	if (callback) {
		return callback(res);
	} else {
		return res;
	}
}

// html编码
export function htmlEncript(str = throwIfMissing(), callback) {
	let s = str;
	if (isString(str)) {
		if (str && s.length > 0) {
			s = s.replace(/&/g, "&amp;");
			s = s.replace(/</g, "&lt;");
			s = s.replace(/>/g, "&gt;");
			s = s.replace(/ /g, "&nbsp;");
			s = s.replace(/\'/g, "&#39;");
			s = s.replace(/\"/g, "&quot;");
		}
	} else {
		console.warn('Variable type should be "String"');
	}
	if (callback) {
		callback(s);
	} else {
		return s;
	}
}

// 解码HTML
export function htmlDecript(str = throwIfMissing(), callback) {
	let s = str;
	if (isString(str)) {
		if (str && s.length > 0) {
			s = s.replace(/&amp;/g, '&');
			s = s.replace(/&lt;/g, '<');
			s = s.replace(/&gt;/g, '>');
			s = s.replace(/&nbsp;/g, ' ');
			s = s.replace(/&#39;/g, "'");
			s = s.replace(/&quot;/g, '"');
		}
	} else {
		console.warn('Variable type should be "String"');
	}
	if (callback) {
		callback(s);
	} else {
		return s;
	}
}
/*
 * @description 登录相关AES加密
 * @method
 * @param {String} paramName desc
 * @return {Object} desc
*/
export function aesEncrypt(word, keyVal = 'mplanyou07558888') {
	var key = CryptoJS.enc.Utf8.parse(keyVal);
	var srcs = CryptoJS.enc.Utf8.parse(word);
	var encrypted = CryptoJS.AES.encrypt(srcs, key, {
		mode: CryptoJS.mode.ECB,
		padding: CryptoJS.pad.Pkcs7
	});
	return encrypted.toString();
}

/**
 * 解密
 */
function decrypt(word, keyVal = 'mplanyou07558888') {
    var key = CryptoJS.enc.Utf8.parse(keyVal);
    var decrypt = CryptoJS.AES.decrypt(word, key, {
        mode: CryptoJS.mode.ECB,
        padding: CryptoJS.pad.Pkcs7
    });
    return CryptoJS.enc.Utf8.stringify(decrypt).toString();
}

// aes加密
// export function aesEncrypt(word = throwIfMissing(), key = '1234123412ABCDEF', iv = 'ABCDEF1234123412') {
// 	let keyVal = CryptoJS.enc.Utf8.parse(key),
// 		keyIv = CryptoJS.enc.Utf8.parse(iv),
// 		srcs = CryptoJS.enc.Utf8.parse(word),
// 		encrypted = CryptoJS.AES.encrypt(srcs, keyVal, {
// 			iv: keyIv,
// 			mode: CryptoJS.mode.CBC,
// 			padding: CryptoJS.pad.Pkcs7
// 		});

// 	return encrypted.ciphertext.toString().toUpperCase();
// }

// aes解密
export function aesDecrypt(word = throwIfMissing(), key = '1234123412ABCDEF', iv = 'ABCDEF1234123412') {
	let keyVal = CryptoJS.enc.Utf8.parse(key),
		keyIv = CryptoJS.enc.Utf8.parse(iv),
		encryptedHexStr = CryptoJS.enc.Hex.parse(word),
		srcs = CryptoJS.enc.Base64.stringify(encryptedHexStr),
		decrypt = CryptoJS.AES.decrypt(srcs, keyVal, {
			iv: keyIv,
			mode: CryptoJS.mode.CBC,
			padding: CryptoJS.pad.Pkcs7
		});

	return decrypt.toString(CryptoJS.enc.Utf8).toString();
}

// 设置用户信息
export function setUserInfo(data, callback) {
	//加密逻辑
	uni.setStorage({
		key: oaconfig.userInfoKey,
		data: data,
		success: function() {
			if (callback && isFunction(callback)) {
				callback();
			}
		}
	})
}

// 获取用户信息
export function getUserInfo() {
	try {
		const value = uni.getStorageSync(oaconfig.userInfoKey);
		//解密
		if (value) {
			return value
		}
		return null;
	} catch (e) {
		return null;
	}
}

// 获取token
export function getToken() {
	const userInfo = getUserInfo();
	if (userInfo) {
		return userInfo.token;
	}
	return '';
}

// 判断是否登录
export function hasLogin(backpage, backtype = 1, callback) {
	/* backtype
	 * 1: redirectTo
	 * 2: switchTab
	 */
	const currentUser = getUserInfo();
	if (currentUser) {
		if (callback && isFunction(callback)) {
			callback(true);
		}
		return true;
	}

	console.log('hasLogin(): 当前会话已过期');
	THIS.$lyRequest.logout('当前会话已过期，请重新登录');
	return false;
}

// 提示信息
export function showTip(title, callback, duration = 3000, mask = false, icon = 'none') {
	//icon = 'none'时title文本在小程序最多可显示两行，5+App仅支持单行显示
	if (Boolean(title) === false || !isString(title) || !isNumber(duration)) return;

	uni.showToast({
		title,
		duration,
		mask,
		icon
	});

	let timer = setTimeout(() => {
		if (callback && isFunction(callback)) {
			callback();
		}
		if (timer) {
			clearTimeout(timer);
		}
	}, duration);
}

// 隐藏信息
export function hideTip() {
	uni.hideToast();
}

// 加载信息，带遮罩
let needLoadingRequestCount = 0;
let loadingTimer;
export function showLoading(title = '', mask = true) {
	if (needLoadingRequestCount === 0) {
		uni.showLoading({
			title,
			mask
		});

		// 最长10s自动关闭
		loadingTimer = setTimeout(() => {
			if (needLoadingRequestCount > 0) {
				uni.hideLoading();
			}
		}, 10000);
	}

	needLoadingRequestCount++;
}

// 隐藏遮罩
export function hideLoading() {
	if (needLoadingRequestCount <= 0) return;

	needLoadingRequestCount--;

	if (needLoadingRequestCount === 0) {
        if (loadingTimer) clearTimeout(loadingTimer);
		uni.hideLoading();
	}
}


// 显示模态框
export function showModal(obj) {
	if (!isString(obj.content)) return;

	//const lang = THIS.$store.state.lang.lang;
	let showCancel = obj.showCancel || true;
	uni.showModal({
		title: obj.title || lang.tip,
		content: obj.content,
		showCancel: showCancel,
		cancelText: obj.cancelText || lang.cancel, //最多4个字符
		cancelColor: obj.cancelColor || '#333333',
		confirmText: obj.confirmText || lang.confirm,
		confirmColor: obj.confirmColor || oaconfig.backgroundColor,
		success: function(res) {
			if (obj.success && isFunction(obj.success)) {
				obj.success(res);
			}
		},
		fail: function(res) {
			if (obj.fail && isFunction(obj.fail)) {
				obj.fail(res);
			}
		},
		complete: function(res) {
			if (obj.complete && isFunction(obj.complete)) {
				obj.complete(res);
			}
		}
	});
}

// 带确认和取消按钮的弹框，标题默认为“提示”
let confirmModalList = [];
export function showModalWithConfirmButton(content, confirmFn, cancelFn, title = lang.tip,
	confirmText = lang.confirm, cancelText = lang.close) {
	if (!isString(content)) return;

	if (!confirmModalList.some(confg => confg.content === content)) {
		confirmModalList.push({
			content,
			confirmFn,
			cancelFn,
			title,
			confirmText,
			cancelText
		});
	}

	function show() {
		if (!confirmModalList.length) return;

		const {
			content,
			confirmFn,
			cancelFn,
			title,
			confirmText,
			cancelText
		} = confirmModalList.shift();

		uni.showModal({
			title,
			content,
			confirmText,
			confirmColor: oaconfig.backgroundColor,
			showCancel: true,
			cancelText,
			cancelColor: '#333333',
			success: function(res) {
				if (res.confirm) {
					confirmFn && isFunction(confirmFn) && confirmFn(res);
					confirmModalList.length && show();
				} else if (res.cancel) {
					cancelFn && isFunction(cancelFn) && cancelFn(res);
					confirmModalList.length && show();
				}
			}
		});
	}

	show();
}

// 带关闭按钮的弹框，标题默认为“提示”
const debounceModal = debounce(500);
export function showModalWithCloseButton(content, closeFn, title = lang.tip, confirmText = lang.close) {
	if (!isString(content)) return;

	debounceModal(() => {
		let pages = getCurrentPages(),
			route = pages.length > 0 ? pages[pages.length - 1].route : void 0;

		// 如果当前已经在登录页并且信息为"当前会话已过期，请重新登录"则不弹框
		if (route && route.indexOf('login/login') != -1 && content === lang.errorCode['_3']) {
			// 避免在登录页接收不到错误请求导致登录按钮加载状态无法结束
			uni.$emit('framework_logout_popMessage', content);
			return;
		}

		uni.showModal({
			title,
			content,
			confirmText,
			showCancel: false,
			confirmColor: oaconfig.backgroundColor,
			success: function(res) {
				if (res.confirm) {
					closeFn && isFunction(closeFn) && closeFn();
				}
			}
		});
	});
}

// 获取当前日期
export function now() {
	let now = new Date();
	return dateFormat(now, 'yyyy-MM-dd');
}

// 日期格式化
export function dateFormat(d, str) {
	//填充0
	var fillZero = function(value) {
		if (value.toString().length < 2) {
			return "0" + value;
		}
		return value;
	};
	//判空
	var checkNull = function(value) {
		if (!value || isNull(value) || isUndefined(value) || value == "") {
			return true;
		}
		return false;
	};

	if (checkNull(str)) { //如果格式化字符为空，返回空字符
		return "";
	}
	if (checkNull(d)) { //如果日期为空，自动获取当前日期
		d = new Date();
	} else if (d.constructor != Date) { //如果参数不是一个日期对象，就认为是一个标准Long值日期
		d = new Date(d);
	}
	return str.replace("yyyy", d.getFullYear()).replace("MM", fillZero(d.getMonth() + 1)).replace("dd", fillZero(d.getDate()))
		.replace("HH", fillZero(d.getHours())).replace("mm", fillZero(d.getMinutes())).replace("ss", fillZero(d.getSeconds()))
		.replace("sss", d.getMilliseconds());
}

// 获取指定时间
export function targetDate(obj) {
	//obj:{type:'day', num: 3, date:'2019-06-26'}
	let num = parseInt(obj.num) || 0;
	let date = obj.date || now();
	date = new Date(date);
	switch (obj.type) {
		case "day":
			date.setDate(date.getDate() + num); //获取AddDayCount天后的日期
			return dateFormat(date, "yyyy-MM-dd");
		case "week":
			date.setDate(date.getDate() + num * 7);
			return dateFormat(date, "yyyy-MM-dd");
		case "month":
			date.setMonth(date.getMonth() + num);
			return dateFormat(date, "yyyy-MM-dd");
		case "year":
			date.setFullYear(date.getFullYear() + num);
			return dateFormat(date, "yyyy-MM-dd");
		case "hours":
			date.setHours(date.getHours() + num);
			return dateFormat(date, "yyyy-MM-dd");
		case "minutes":
			date.setMinutes(date.getMinutes() + num);
			return dateFormat(date, "yyyy-MM-dd");
		case "seconds":
			date.setSeconds(date.getSeconds() + num);
			return dateFormat(date, "yyyy-MM-dd");
		default:
			return null;
	}
}

/**
 * 取出中括号内的内容
 * @param text
 * @returns {string}
 */
export function getBracketStr(text) {
	let result = '';

	if (isNull(text)) return result

	let regex = /\[(.+?)\]/g;
	let options = text.match(regex);

	if (!isNull(options)) {
		let option = options[0];
		if (!isNull(option)) {
			result = option.substring(1, option.length - 1);
		}
	}

	return result;
}

/**
 * 取出小括号内的内容
 * @param text
 * @returns {string}
 */
export function getParenthesesStr(text) {
	let result = ''
	if (isNull(text))
		return result
	let regex = /\((.+?)\)/g;
	let options = text.match(regex)
	if (!isNull(options)) {
		let option = options[0]
		if (!isNull(option)) {
			result = option.substring(1, option.length - 1)
		}
	}
	return result
}

// 设置搜索的历史记录
export function setQuickKey(key, value) {
	if (!value) {
		return;
	}
	let arr = getPageStorage("FRAMEWORK_SEARCH_KEY", key) || [];

	//是否已经包含当前value值
	let hasContain = false;
	for (let i = 0; i < arr.length; i++) {
		if (value == arr[i]) {
			hasContain = true;
		}
	}
	if (hasContain) {
		return arr;
	} else {
		arr.push(value);
	}
	//最多保存10条记录
	if (arr.length >= 10) {
		arr = arr.slice(arr.length - 10, arr.length);
	}
	setPageStorageByKey('FRAMEWORK_SEARCH_KEY', key, arr);
	return arr;
}

// 移除历史数据
export function removeQuickKey(key, index) {
	let arr = getPageStorage("FRAMEWORK_SEARCH_KEY", key) || [];

	//是否已经包含当前value值
	if (arr.length > Number(index)) {
		arr.del(index)
	}
	setPageStorageByKey('FRAMEWORK_SEARCH_KEY', key, arr);
	return arr;
}

export function removeAllQuickKey(key) {
	if (!key) {
		return;
	}
	setPageStorageByKey('FRAMEWORK_SEARCH_KEY', key, []);
	return [];
}

// 获取搜索的历史记录
export function getQuickKeyList(key) {
	let words = getPageStorage("FRAMEWORK_SEARCH_KEY", key) || [];
	return words;
}

// 设置页面缓存
export function setPageStorageByKey(pageName, key, value) {
	try {
		if (!getUserInfo()) return null;

		if (!pageName || !key) {
			throw new Error('[pageName] and [key] is required!');
		};

		let storageInfo = uni.getStorageSync(pageName),
			userId = getUserInfo().ly_id,
			thisUserInfo = null,
			newStorageInfo = {};

		if (isObject(storageInfo) && storageInfo[userId]) {
			thisUserInfo = storageInfo[userId];
		}

		if (!thisUserInfo || !isObject(thisUserInfo)) thisUserInfo = {};
		thisUserInfo[key] = value;

		newStorageInfo[userId] = thisUserInfo;
		uni.setStorageSync(pageName, newStorageInfo);
	} catch (e) {
		console.error('setPageStorageByKey():::', e);
	}

}

// 获取页面缓存
export function getPageStorage(pageName, key) {
	try {
		if (!getUserInfo()) return null;

		let storageInfo = uni.getStorageSync(pageName),
			userId = getUserInfo().ly_id,
			thisUserInfo = {};

		if (isObject(storageInfo) && storageInfo[userId]) {
			thisUserInfo = storageInfo[userId];
		}

		if (!thisUserInfo) return null;

		if (!key || isString(thisUserInfo)) return thisUserInfo;
		if (isObject(thisUserInfo)) return thisUserInfo[key];
		return null;
	} catch (e) {
		console.error('getPageStorage():::', e);
	}
}

// 请求200，但result为0的情景
export function unSuccessHandleFn() {
	let desc = '',
		result;

	if (arguments[0] && isString(arguments[0])) {
		desc = arguments[0];
		if (arguments[1] && isObject(arguments[1])) {
			result = arguments[1];
		}
	} else {
		if (arguments[0] && isObject(arguments[0])) {
			result = arguments[0];
		}
	}

	if (result && result.message) {
		let msg = result.message.replace('${}', desc),
			pages = getCurrentPages();

		// 处理某些情况下请求响应延时,用户已经离开页面的情况
		let route = pages.length > 0 ? pages[pages.length - 1].route : undefined;

		if (!result.route || !route || route === result.route) {
			showModalWithCloseButton(msg);
		}
	}
}

// 统一的错误处理方法，请求超时/参数异常等
export function errorHandleFn(e) {
	// 不弹出代码异常
	if (e.constructor === new Error().constructor) {
		console.error(e);
		return;
	}

	if (e.message && e.message != '当前网络不给力哦~请检查您的网络状态') {
		let pages = getCurrentPages();

		// 处理某些情况下请求响应延时,用户已经离开页面的情况
		let route = pages.length > 0 ? pages[pages.length - 1].route : undefined;

		if (!e.route || !route || route === e.route) {
			showModalWithCloseButton(e.message.replace('${}', ''));
		}
	}
}

// 数组排序，首先根据field1进行排序，如果field1的值相等，根据field2的值进行排序
export function sortBy(field1, field2) {
	return (a, b) => {
		if (a[field1] == b[field1]) return a[field2] - b[field2];
		return a[field1] - b[field1];
	}
}

// 24小时制转换为12小时制
export function formateH(str) {
	str = Number(arguments[0]) || 0;
	let h = str > 12 ? (str - 12) : (str + '');
	if (h.length == 1) {
		h = '0' + h;
	}
	return h;
}

// 图片缓存,image_url:完整的图片下载路径;image_name:图片名,必须唯一,如guid;callback:回调
export function getImageCache(image_url, image_name, callback) {
	try {
		// #ifdef H5
		//h5不进行缓存
		callback(image_url);
		// #endif

		// #ifndef H5
		let storageInfo = extend({}, uni.getStorageSync('FRAMEWORK_IMAGE_CACHE_INFO'));
		let url = storageInfo[image_name];
		if (url) {
			callback(url);
		} else {
			// 为避免首次加载不出图片,需要先将原路径返回后下载图片存储
			callback(image_url);

			THIS.$lyRequest.downloadFile(image_url, {
				loading: false
			}).then(({
				data
			}) => {
				uni.saveFile({
					tempFilePath: data.filePath,
					success: (saveRes) => {
						let storageInfo = extend({}, uni.getStorageSync('FRAMEWORK_IMAGE_CACHE_INFO'));
						storageInfo[image_name] = saveRes.savedFilePath;
						uni.setStorageSync('FRAMEWORK_IMAGE_CACHE_INFO', storageInfo);
					}
				})
			});
		}
		// #endif
	} catch (e) {
		console.error('getImageCache():::', e);
	}
}

export function isNetworkCanUse(callback) {
	if (!callback || !isFunction(callback)) throw new Error(
		'isNetworkCanUse(): callback is required and bust be function type.');

	uni.getNetworkType({
		success: res => {
			if (res.networkType === 'none') {
				callback(false);
			} else {
				callback(true);
			}
		},
		fail() {
			callback(false);
		}
	});
}

export function isAndroid() {
	try {
		const platform = uni.getSystemInfoSync().platform;
		return platform === 'android';
	} catch (e) {
		console.error('isAndroid():::', e);
	}
}

export function isIOS() {
	try {
		const platform = uni.getSystemInfoSync().platform;
		return platform === 'ios';
	} catch (e) {
		console.error('isIOS():::', e);
	}
}

export function getUuid() {
	try {
		let uuid = '';

		// #ifdef APP-PLUS
		uuid = plus.device.uuid;
		// #endif

		// #ifndef APP-PLUS
		uuid = getPageStorage('FRAMEWORK_DEVICE_INFO', 'uuid');

		if (!uuid) {
			uuid = guid();
			setPageStorageByKey('FRAMEWORK_DEVICE_INFO', 'uuid', uuid);
		}
		// #endif

		return uuid;
	} catch (e) {
		//TODO handle the exception
		return '123456789';
	}
}

export function getDeviceInfo(key) {
	try {
		let value = '';

		// #ifdef APP-PLUS
		value = plus.device[key];
		// #endif

		// #ifndef APP-PLUS
		value = getPageStorage('FRAMEWORK_DEVICE_INFO', key);

		if (!value) {
			value = guid();
			setPageStorageByKey('FRAMEWORK_DEVICE_INFO', key, value);
		}
		// #endif

		return value;
	} catch (e) {
		//TODO handle the exception
		return guid();
	}
}

export function getSystemInfo() {
	try {
		let sysInfoObj = uni.getSystemInfoSync();

		// #ifdef APP-PLUS
		sysInfoObj = Object.assign(sysInfoObj, plus.device);
		// #endif

		// #ifdef H5
		sysInfoObj = Object.assign(sysInfoObj, {
			imei: getDeviceInfo('imei'),
			imsi: getDeviceInfo('imsi'),
			model: getDeviceInfo('model'),
			vender: getDeviceInfo('vender'),
			uuid: getDeviceInfo('uuid')
		});
		// #endif

		return sysInfoObj;
	} catch (e) {
		console.error(e);
		return null;
	}
}

export function encryptedmailbox(email) {
	if (!email || !isString(email)) throw new Error('encryptedmailbox(): email is required and of string type');

	let new_email = email;

	if (email.indexOf('@') > 0) {
		let str = email.split('@'),
			length = str[0].length;

		if (length >= 5) { // @前面大于等于5位
			new_email = str[0].substr(0, length - 4) + '****' + '@' + str[1];
		} else { // @前面小于5位
			new_email = str[0].substr(0, length - 1) + '*' + '@' + str[1];
		}
	}

	return new_email;
}

// 时间格式化:如果是当天，则显示时分; 如果非当天，显示日期
export function timeFilter(time) {
	if (!time) return '';

	return now() === time.substring(0, 10) ? time.substring(11, 16) : time.substring(5, 10);
}

//输出对象
var index_esm = {
	throwIfMissing,
	debounce,
	throttle,
	isName,
	isEmail,
	isTelPhone,
	isMobile,
	isBirthDay,
	isQQ,
	isJson,
	isArray,
	isNull,
	isUndefined,
	isNumber,
	isString,
	isObject,
	isPlainObject,
	strlen,
	inArray,
	isFunction,
	extend,
	deepClone,
	getRandom,
	guid,
	formChecked,
	md5Encript,
	base64Encript,
	base64Decript,
	base64EncriptURI,
	htmlEncript,
	htmlDecript,
	aesEncrypt,
	aesDecrypt,
	setUserInfo,
	getUserInfo,
	getToken,
	hasLogin,
	showTip,
	hideTip,
	showLoading,
	hideLoading,
	showModal,
	showModalWithConfirmButton,
	showModalWithCloseButton,
	now,
	dateFormat,
	targetDate,
	navigateTo,
	redirectTo,
	reLaunch,
	switchTab,
	navigateBack,
	setUrlParams,
	getUrlRelativePath,
	parseUrlParams,
	getBracketStr,
	getParenthesesStr,
	setQuickKey,
	removeQuickKey,
	removeAllQuickKey,
	getQuickKeyList,
	setPageStorageByKey,
	getPageStorage,
	unSuccessHandleFn,
	errorHandleFn,
	sortBy,
	formateH,
	getImageCache,
	isNetworkCanUse,
	isAndroid,
	isIOS,
	getUuid,
	getDeviceInfo,
	getSystemInfo,
	encryptedmailbox,
	timeFilter,
	decrypt
}

export default index_esm;
